#include <iostream>
#include <typeinfo>
#include <stdlib.h>
#include <string.h>

#include "pidgindbus.h"
#include "dbus-service.h"
#include "utils.h"
#include "prpl.h"
#include "request.h"

using namespace std;


void xmlnode_received_cb(PurpleConnection *gc, xmlnode **packet, gpointer null)
{
	printf( "Received Raw triggered! " );

	xmlnode *recv = xmlnode_copy(*packet);
	int *str_len;
	char *str = xmlnode_to_str( recv, str_len );

	printf("Received Raw: %s \n", str );

	if( !strcmp( recv->name, "message") ) {
		const char *type;
		const char *from;
		const char *to; 
		const char *body;

		type = xmlnode_get_attrib( recv, "type");

		if( type && ( !strcmp(type, "normal") || !strcmp(type, "chat") ) )
		{
			from = g_strdup(xmlnode_get_attrib( recv, "from"));
			to   = g_strdup(xmlnode_get_attrib( recv, "to"));

			for( xmlnode *child = recv->child; child; child = child->next) {
				const char *xmlns = xmlnode_get_namespace(child);
				if(child->type != XMLNODE_TYPE_TAG) { continue; }

				//if( !strcmp(child->name, "wb") && !strcmp(xmlns,"http://inkscape.org/inkboard")) {
				if( !strcmp(child->name, "inkboard") ) {
					string serial   = g_strdup(xmlnode_get_attrib( child, "id"));
					string app      = g_strdup(xmlnode_get_attrib( child, "app"));

					const char *data =  xmlnode_get_data(child);
					if ( data != NULL ){
						string recv_data( base64_decode( string( data ) ) );
						processIncomingMessageFromPidgin( to, from, serial, app, recv_data );
					}
				} 		
			}
		}
	}
	xmlnode_free( recv );
}


void xmlnode_sent_cb(PurpleConnection *gc, char **packet, gpointer null)
{
	// do nothing...
}

/**************************************************************************
 * File transfer signal callbacks
 **************************************************************************/
void
ft_recv_start_cb(PurpleXfer *xfer, gpointer data) {
        fprintf( stderr,"file receive started\n");
}

void
ft_send_start_cb(PurpleXfer *xfer, gpointer data) {
        fprintf( stderr,"file send started\n");
}

void
ft_recv_cancel_cb(PurpleXfer *xfer, gpointer data) {
        fprintf( stderr,"file receive canceled\n");
}

void
ft_send_cancel_cb(PurpleXfer *xfer, gpointer data) {
        fprintf( stderr,"file send canceled\n");
}

void
ft_recv_complete_cb(PurpleXfer *xfer, gpointer data) 
{
        fprintf( stderr,"file receive completed %x #\n", (unsigned int)xfer);
        fprintf( stderr,"file receive completed %s #\n", xfer->who);
        fprintf( stderr,"file receive completed %s #\n", xfer->filename);
        fprintf( stderr,"file receive completed %s #\n", xfer->local_filename);
}

void
ft_send_complete_cb(PurpleXfer *xfer, gpointer data) 
{
        fprintf( stderr,"file send completed %x #\n", (unsigned int)xfer);
        fprintf( stderr,"file send completed %s #\n", xfer->who);
        fprintf( stderr,"file send completed %s #\n", xfer->filename);
        fprintf( stderr,"file send completed %s #\n", xfer->local_filename);
}

#ifdef _WIN32
#include <windows.h>
#include <tchar.h>

DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
    //system( "ping -n 60 127.0.0.1" );
    PiDBus::getInstance();
    //std::cerr << "dbus_start_thread win32"  << std::endl;
    return 0;
}
#else
void *dbus_start_thread(void *arg)
{
	std::cerr << "dbus_start_thread"  << std::endl;
	PiDBus::getInstance();
}
#endif

void 
plugin_load_hook()
{
#ifdef _WIN32
	DWORD   dwThreadId;
	HANDLE  hThread;

	hThread = CreateThread(
		NULL,                   // default security attributes
		0,                      // use default stack size
		MyThreadFunction,       // thread function name
		NULL,            // argument to thread function
		0,                      // use default creation flags
		&dwThreadId);   // returns the thread identifier

		if (hThread == NULL) {
			ExitProcess(3);
		}
#else
	pthread_t threads;
	pthread_create( &threads, NULL, dbus_start_thread, NULL);
#endif
}
